import * as vscode from 'vscode';
import { runSemgrepScan, ScanResult, getChangedLines } from './scanner';
import { callDeepSeekAPI, AIResult } from './ai';
import { showScanResultsWebview } from './ui';
import { generateRuleFix, getAIFix } from './fixer';
import { exportComplianceReport } from './report';
import * as fs from 'fs';
import * as path from 'path';

function getRecommendedRuleId(filePath: string): string {
  const ext = path.extname(filePath).toLowerCase();
  if (ext === '.py') return 'p/python';
  if (ext === '.js') return 'p/javascript';
  if (ext === '.java') return 'p/java';
  if (ext === '.c' || ext === '.cpp') return 'p/c';
  return 'p/r2c-cwe-top-25';
}

export function activate(context: vscode.ExtensionContext) {
  // 读取插件配置
  const config = vscode.workspace.getConfiguration('aiCodeVulnGuard');
  const rulesPathOrId = config.get('rulesPathOrId', 'auto');
  const apiKey = config.get('deepSeekApiKey', '');
  const apiUrl = config.get('deepSeekApiUrl', 'https://api.deepseek.com/analyze');

  // 多文件扫描命令
  let scanDisposable = vscode.commands.registerCommand('extension.scanCode', async () => {
    try {
      const files = await vscode.window.showOpenDialog({ canSelectMany: true, filters: { '代码文件': ['js', 'py', 'java', 'c', 'cpp'] } });
      if (!files || files.length === 0) {
        vscode.window.showWarningMessage('请选择需要扫描的代码文件');
        return;
      }
      for (const fileUri of files) {
        const filePath = fileUri.fsPath;
        let rulesConfig = rulesPathOrId;
        if (rulesPathOrId === 'auto') {
          rulesConfig = getRecommendedRuleId(filePath);
        }
        const scanType = await vscode.window.showQuickPick([
          '增量扫描（仅变更行）',
          '全量扫描（所有行）'
        ], { placeHolder: `请选择${path.basename(filePath)}的扫描模式 (规则: ${rulesConfig})` });
        if (!scanType) continue;
        let onlyLines: number[] | undefined = undefined;
        if (scanType.startsWith('增量')) {
          onlyLines = getChangedLines(filePath);
          if (onlyLines.length === 0) {
            vscode.window.showWarningMessage('未检测到变更行，将执行全量扫描');
            onlyLines = undefined;
          }
        }
        vscode.window.showInformationMessage(`正在扫描: ${filePath}，规则: ${rulesConfig}`);
        try {
          const semgrepResults: ScanResult[] = await runSemgrepScan(filePath, rulesConfig, onlyLines);
          const code = fs.readFileSync(filePath, 'utf-8');
          const aiResults: AIResult[] = await callDeepSeekAPI(code, filePath, apiKey, apiUrl);
          showScanResultsWebview(semgrepResults, aiResults, filePath);
        } catch (e: any) {
          vscode.window.showErrorMessage('扫描失败: ' + (e.message || e));
          fs.appendFileSync('ai-vuln-guard.log', `[${new Date().toISOString()}] ${e.stack || e}\n`);
        }
      }
    } catch (e: any) {
      vscode.window.showErrorMessage('扫描命令异常: ' + (e.message || e));
      fs.appendFileSync('ai-vuln-guard.log', `[${new Date().toISOString()}] ${e.stack || e}\n`);
    }
  });

  // 导出扫描结果为JSON
  let exportJsonDisposable = vscode.commands.registerCommand('extension.exportScanJson', async () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      vscode.window.showWarningMessage('请先打开需要导出的代码文件');
      return;
    }
    const filePath = editor.document.fileName;
    const semgrepResults: ScanResult[] = await runSemgrepScan(filePath, getRecommendedRuleId(filePath));
    const code = fs.readFileSync(filePath, 'utf-8');
    const aiResults: AIResult[] = await callDeepSeekAPI(code, filePath, apiKey, apiUrl);
    const outPath = filePath + '.scan.json';
    fs.writeFileSync(outPath, JSON.stringify({ semgrepResults, aiResults }, null, 2));
    vscode.window.showInformationMessage('扫描结果已导出: ' + outPath);
  });

  // 查看日志
  let viewLogDisposable = vscode.commands.registerCommand('extension.viewLog', () => {
    const logPath = path.join(__dirname, '../ai-vuln-guard.log');
    if (fs.existsSync(logPath)) {
      vscode.window.showTextDocument(vscode.Uri.file(logPath));
    } else {
      vscode.window.showInformationMessage('暂无日志文件');
    }
  });

  // 反馈命令
  let feedbackDisposable = vscode.commands.registerCommand('extension.feedback', () => {
    vscode.env.openExternal(vscode.Uri.parse('https://wj.qq.com/s/xxxxxxx'));
  });

  // 注册一键修复命令
  let fixDisposable = vscode.commands.registerCommand('extension.fixVuln', async () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      vscode.window.showWarningMessage('请先打开需要修复的代码文件');
      return;
    }
    const filePath = editor.document.fileName;
    const code = fs.readFileSync(filePath, 'utf-8');
    // 规则修复建议
    const semgrepResults: ScanResult[] = await runSemgrepScan(filePath, 'cwe-top-25.yml');
    let fixedCode = code;
    let fixMessages: string[] = [];
    for (const r of semgrepResults) {
      const fix = generateRuleFix(fixedCode, r);
      if (fix && fix !== fixedCode) {
        fixMessages.push(`[规则][${r.ruleId}] 行${r.line} 修复建议已应用`);
        fixedCode = fix;
      }
    }
    // AI修复建议
    const aiResults: AIResult[] = await callDeepSeekAPI(code, filePath);
    for (const r of aiResults) {
      const fix = getAIFix(r);
      if (fix) {
        fixMessages.push(`[AI] 行${r.line} 修复建议：${fix}`);
      }
    }
    // 展示修复建议
    if (fixMessages.length === 0) {
      vscode.window.showInformationMessage('未发现可自动修复的内容');
    } else {
      vscode.window.showInformationMessage('修复建议：\n' + fixMessages.join('\n'));
      // 可选：自动写回fixedCode到文件，需用户确认
    }
  });

  // 注册导出报告命令
  let reportDisposable = vscode.commands.registerCommand('extension.exportReport', async () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      vscode.window.showWarningMessage('请先打开需要导出报告的代码文件');
      return;
    }
    const filePath = editor.document.fileName;
    vscode.window.showInformationMessage('正在生成合规报告...');
    // 规则与AI扫描
    const semgrepResults: ScanResult[] = await runSemgrepScan(filePath, 'cwe-top-25.yml');
    const code = fs.readFileSync(filePath, 'utf-8');
    const aiResults: AIResult[] = await callDeepSeekAPI(code, filePath);
    // 导出PDF
    const outPath = filePath + '.compliance_report.pdf';
    exportComplianceReport(filePath, semgrepResults, aiResults, outPath);
    vscode.window.showInformationMessage('合规报告已导出: ' + outPath);
  });

  context.subscriptions.push(scanDisposable, exportJsonDisposable, viewLogDisposable, feedbackDisposable);
}

export function deactivate() {} 